﻿// Copyright © Microsoft Corporation.  All Rights Reserved.
// This code released under the terms of the 
// Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)

namespace Microsoft.Expression.Prototyping.Mockups
{
	using System;
	using System.Windows;
	using System.Windows.Controls;
	using System.Windows.Media;

	public enum CursorHighlight
	{
		NoHighlight,
		CircleHighlight,
		SquareHighlight,
		SketchyHighlight,
		GlowingHighlight,
		ClickHighlight
	}

	public enum CursorImage
	{
		ArrowAll,
		ArrowLeftRight,
		ArrowLeftTopRightBottom,
		ArrowRightTopLeftBottom,
		ArrowUpDown,
		Ball,
		Crosshair,
		Cursor,
		FingerPointer,
		Hourglass,
		IBeam,
		Invalid,
		MouseLeftDown,
		MouseMiddleDown,
		MouseNoneDown,
		MouseRightDown,
		None,
		Pan,
		Pencil,
		Zoom
	}

	public enum CursorOverlay
	{
		Hourglass,
		Invalid,
		MouseLeftDown,
		MouseMiddleDown,
		MouseNoneDown,
		MouseRightDown,
		None,
		QuestionMark
	}

	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "NoHighlight")]
	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "CircleHighlight")]
	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "SquareHighlight")]
	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "SketchyHighlight")]
	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "GlowingHighlight")]
	[TemplateVisualStateAttribute(GroupName = "CursorHighlight", Name = "ClickHighlight")]

	public class CursorMockup : Control
	{
		public static readonly DependencyProperty CursorImageProperty = DependencyProperty.Register("CursorImage", typeof(CursorImage), typeof(CursorMockup), new PropertyMetadata(CursorImage.Cursor, new PropertyChangedCallback(CursorImageChanged)));

		public CursorImage CursorImage
		{
			get { return (CursorImage)GetValue(CursorImageProperty); }
			set { SetValue(CursorImageProperty, value); }
		}

		private static void CursorImageChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
		{
			((CursorMockup)sender).OnCursorImageChanged(e);
		}

		protected virtual void OnCursorImageChanged(DependencyPropertyChangedEventArgs e)
		{
			this.InvalidateArrange();
		}

		public static readonly DependencyProperty CursorOverlayProperty = DependencyProperty.Register("CursorOverlay", typeof(CursorOverlay), typeof(CursorMockup), new PropertyMetadata(CursorOverlay.None, (o, e) => { ((CursorMockup)o).InvalidateArrange(); }));

		public CursorOverlay CursorOverlay
		{
			get { return (CursorOverlay)GetValue(CursorOverlayProperty); }
			set { SetValue(CursorOverlayProperty, value); }
		}

		public static readonly DependencyProperty CursorHighlightProperty = DependencyProperty.Register("CursorHighlight", typeof(CursorHighlight), typeof(CursorMockup), new PropertyMetadata(CursorHighlight.NoHighlight, new PropertyChangedCallback(CursorHighlightChanged)));

		public CursorHighlight CursorHighlight
		{
			get { return (CursorHighlight)this.GetValue(CursorHighlightProperty); }
			set { this.SetValue(CursorHighlightProperty, value); }
		}

		private static void CursorHighlightChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
		{
			((CursorMockup)sender).OnCursorHighlightChanged(e);
		}

		protected virtual void OnCursorHighlightChanged(DependencyPropertyChangedEventArgs e)
		{
			VisualStateManager.GoToState(this, this.CursorHighlight.ToString(), true);
			this.InvalidateArrange();
		}

		public CursorMockup()
		{
			// Insert code required on object creation below this point.
			base.DefaultStyleKey = typeof(CursorMockup);
		}

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			VisualStateManager.GoToState(this, Enum.GetName(typeof(CursorHighlight), this.CursorHighlight), false);
		}

		protected override Size ArrangeOverride(Size finalSize)
		{
			FrameworkElement placementGrid = this.GetTemplateChild("PlacementGrid") as FrameworkElement;
			IconMockup cursorImage = this.GetTemplateChild("cursorImage") as IconMockup;

			if (placementGrid != null && cursorImage != null)
			{
				double translateX = 0.0;
				double translateY = 0.0;

				switch (cursorImage.OriginLocation)
				{
					case OriginLocation.Left:
					case OriginLocation.TopLeft:
					case OriginLocation.BottomLeft:
						translateX = 0;
						break;

					case OriginLocation.Right:
					case OriginLocation.TopRight:
					case OriginLocation.BottomRight:
						translateX = -finalSize.Width;
						break;

					case OriginLocation.Top:
					case OriginLocation.Bottom:
					case OriginLocation.Center:
					default:
						translateX = -finalSize.Width / 2;
						break;
				}

				switch (cursorImage.OriginLocation)
				{
					case OriginLocation.Top:
					case OriginLocation.TopLeft:
					case OriginLocation.TopRight:
						translateY = 0;
						break;

					case OriginLocation.Bottom:
					case OriginLocation.BottomLeft:
					case OriginLocation.BottomRight:
						translateY = -finalSize.Height;
						break;

					case OriginLocation.Left:
					case OriginLocation.Right:
					case OriginLocation.Center:
					default:
						translateY = -finalSize.Height / 2;
						break;
				}

				TranslateTransform transform = placementGrid.RenderTransform as TranslateTransform;
				if (transform == null)
				{
					transform = new TranslateTransform();
					placementGrid.RenderTransform = transform;
				}

				transform.X = translateX;
				transform.Y = translateY;

				FrameworkElement highlightsGrid = this.GetTemplateChild("HighlightsGrid") as FrameworkElement;
				if (highlightsGrid != null)
				{
					TranslateTransform highlightsTransform = highlightsGrid.RenderTransform as TranslateTransform;
					if (highlightsTransform == null)
					{
						highlightsTransform = new TranslateTransform();
						highlightsGrid.RenderTransform = highlightsTransform;
					}

					highlightsTransform.X = -finalSize.Width / 2 - translateX;
					highlightsTransform.Y = -finalSize.Height / 2 - translateY;
				}

				IconMockup cursorOverlay = this.GetTemplateChild("cursorOverlay") as IconMockup;
				if (cursorOverlay != null && cursorOverlay.IconImage != IconImage.None)
				{
					TranslateTransform overlayTransform = cursorOverlay.RenderTransform as TranslateTransform;
					if (overlayTransform == null)
					{
						overlayTransform = new TranslateTransform();
						cursorOverlay.RenderTransform = overlayTransform;
					}

					overlayTransform.X = cursorImage.OverlayLocation.X * finalSize.Width;
					overlayTransform.Y = cursorImage.OverlayLocation.Y * finalSize.Height;
				}
			}

			return base.ArrangeOverride(finalSize);
		}
	}
}